﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using Notes.Resources;
using System.IO;
using System.Diagnostics;
using System.Threading;

using Microsoft.Phone.Notification;
using Microsoft.Phone.Tasks;
using System.Xml.Serialization;
using NotesAgent;
using System.Windows.Media.Imaging;

namespace Notes
{
    public partial class NotePage : PhoneApplicationPage
    {



        public int MAX_SECONDS = 60;
        public int remainingSeconds = 0;
        public Timer timer;
        public static note SelectedNote = new note();
        bool working = false;
        CameraCaptureTask cameraCaptureTask;
        bool ImageModified = false;
        byte[] byteArray;
        public NotePage()
        {
            /// Holds the push channel that is created or found.

            PhoneApplicationService.Current.ApplicationIdleDetectionMode = IdleDetectionMode.Disabled;
            InitializeComponent();

            SetElements();

            BuildApplicationBar();

            working = false;

            cameraCaptureTask = new CameraCaptureTask();
            cameraCaptureTask.Completed += new EventHandler<PhotoResult>(cameraCaptureTask_Completed);
        }

        public void BuildApplicationBar()
        {
            ApplicationBar.Buttons.Clear();
            ApplicationBarIconButton save = new ApplicationBarIconButton() { Text = Strings.Save, IsEnabled = true };
            if (App.CurrentTheme == App.Theme.Dark)
                save.IconUri = new Uri("\\Images\\dark\\appbar.save.rest.png", UriKind.Relative);
            else
                save.IconUri = new Uri("\\Images\\light\\appbar.save.rest.png", UriKind.Relative);
            save.Click += Save_Button_Click;
            ApplicationBar.Buttons.Add(save);


            bool addPin = SelectedNote.Id != 0;
            if (SelectedNote.Id != 0)
            {
                /*var tiles = ShellTile.ActiveTiles.ToList();
                for (int i = 0; i < tiles.Count; i++)
                {
                    if (tiles[i].NavigationUri.ToString().Contains("id=" + SelectedNote.Id))
                    //if (tiles[i].Id==""+SelectedNote.Id)
                    {
                        addPin = false;
                        break;
                    }
                }*/
                ShellTile shellTile = ShellTile.ActiveTiles.FirstOrDefault(
                tile => tile.NavigationUri.ToString().Contains("id=" + SelectedNote.Id));
                if (shellTile != null)
                    addPin = false;
            }
            if (addPin)
            {
                ApplicationBarIconButton pin = new ApplicationBarIconButton() { Text = Strings.PinTile, IsEnabled = true };
                if (App.CurrentTheme == App.Theme.Dark)
                    pin.IconUri = new Uri("\\Images\\dark\\appbar.pin.rest.png", UriKind.Relative);
                else
                    pin.IconUri = new Uri("\\Images\\light\\appbar.pin.rest.png", UriKind.Relative);
                pin.Click += Pin_Button_Click;
                ApplicationBar.Buttons.Add(pin);
            }

            ApplicationBarIconButton delete = new ApplicationBarIconButton() { Text = Strings.Delete, IsEnabled = true };
            if (App.CurrentTheme == App.Theme.Dark)
                delete.IconUri = new Uri("\\Images\\dark\\appbar.delete.rest.png", UriKind.Relative);
            else
                delete.IconUri = new Uri("\\Images\\light\\appbar.delete.rest.png", UriKind.Relative);
            delete.Click += Delete_Button_Click;
            ApplicationBar.Buttons.Add(delete);

            SetElements();
        }


        private void Save_Button_Click(object sender, EventArgs e)
        {
            if (Title_Area.Text == "")
            {
                MessageBox.Show(Strings.TitleCannotBeEmpty);
                return;
            }
            Save();
        }

        private void Delete_Button_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show(Strings.ConfirmDelete, Strings.Confirm, MessageBoxButton.OKCancel) == MessageBoxResult.OK)
            {
                if (SelectedNote.Id == 0)
                {
                    NavigationService.GoBack();
                }
                else
                {
                    Delete();
                }
            }
        }

        public void SetElements()
        {
            ApplicationBar.IsVisible = true;
            //PageTitle.Text = Strings.Title;
            Text_Text.Visibility = System.Windows.Visibility.Visible;
            Title_Text.Visibility = System.Windows.Visibility.Visible;
            Text_Area.Visibility = System.Windows.Visibility.Visible;
            Title_Area.Visibility = System.Windows.Visibility.Visible;

            CancelUpdate_Button.Visibility = System.Windows.Visibility.Collapsed;

            RemainingTime_Label.Visibility = System.Windows.Visibility.Collapsed;

            Title_Area.Text = SelectedNote.Title;
            Text_Area.Text = SelectedNote.Text;

            if (SelectedNote.Type == 1)
            {
                Image.Visibility = System.Windows.Visibility.Visible;
                Image_Text.Visibility = System.Windows.Visibility.Visible;
                Image.Source = new System.Windows.Media.Imaging.BitmapImage(new Uri("http://fboscari.altervista.org/Notes/" + SelectedNote.Payload, UriKind.RelativeOrAbsolute));
            }

            ShowHideElements();
        }

        public void ShowHideElements()
        {
            if (SelectedNote.Type <= 1)
            {
                Image.Visibility = System.Windows.Visibility.Visible;
                Image_Text.Visibility = System.Windows.Visibility.Visible;
                CapturePhoto_Button.Visibility = System.Windows.Visibility.Visible;
            }
            else
            {
                Image.Visibility = System.Windows.Visibility.Collapsed;
                Image_Text.Visibility = System.Windows.Visibility.Collapsed;
                CapturePhoto_Button.Visibility = System.Windows.Visibility.Collapsed;
            }
        }

        public void ToggleOverlay(bool isOpen)
        {
            working = isOpen;
            if (isOpen)
            {
                //PageTitle.Text = Strings.Working;
                //Current_Step_Label.Visibility = System.Windows.Visibility.Visible;
                CancelUpdate_Button.Visibility = System.Windows.Visibility.Visible;
                RemainingTime_Label.Visibility = System.Windows.Visibility.Visible;
                EnableProgressBar();
                ApplicationBar.IsVisible = false;

                Text_Text.Visibility = System.Windows.Visibility.Collapsed;
                Title_Text.Visibility = System.Windows.Visibility.Collapsed;
                Text_Area.Visibility = System.Windows.Visibility.Collapsed;
                Title_Area.Visibility = System.Windows.Visibility.Collapsed;

                Image.Visibility = System.Windows.Visibility.Collapsed;
                Image_Text.Visibility = System.Windows.Visibility.Collapsed;
                CapturePhoto_Button.Visibility = System.Windows.Visibility.Collapsed;
            }
            else
            {
                DisableProgressBar();
                ApplicationBar.IsVisible = true;
                //PageTitle.Text = Strings.Title;
                Text_Text.Visibility = System.Windows.Visibility.Visible;
                Title_Text.Visibility = System.Windows.Visibility.Visible;
                Text_Area.Visibility = System.Windows.Visibility.Visible;
                Title_Area.Visibility = System.Windows.Visibility.Visible;

                CancelUpdate_Button.Visibility = System.Windows.Visibility.Collapsed;

                RemainingTime_Label.Visibility = System.Windows.Visibility.Collapsed;

                ShowHideElements();
            }
            if (Storage.IsFirstOpening())
            {
                MessageBox.Show(Strings.Disclaimer_Once);
                Storage.SetAlreadyOpened();
            }
        }

        protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);
            try
            {
                var id_s = this.NavigationContext.QueryString["id"];
                int id = Int32.Parse(id_s);
                //if (!(Int32.TryParse(id_s, out id)))
                //{
                Account acc = Storage.LoadAccount();
                if (!acc.IsActive())
                {
                    MessageBox.Show(Strings.NoSavedAccount);
                    return;
                }
                ToggleOverlay(true);
                MainPage.currentAccount = acc;
                ScheduledAgent.GetResult(MainPage.currentAccount, result =>
                {
                    Dispatcher.BeginInvoke(() =>
                    {
                        NotesPage.result = result;
                        Storage.SaveResult(result);
                        SelectedNote = NotesPage.result.notes.First(n => n.Id == id);
                        Title_Area.Text = SelectedNote.Title;
                        Text_Area.Text = SelectedNote.Text;
                        ToggleOverlay(false);
                    });
                }
                ,
                () =>
                {
                    Dispatcher.BeginInvoke(() =>
                    {
                        ApplicationBar.Buttons.Clear();
                    });
                    OnError(Strings.ConnectionError);
                }
                );
                //}
            }
            catch (Exception ex)
            {
                ex.ToString();
            }
        }

        public void OnError(string message)
        {
            Dispatcher.BeginInvoke(() =>
            {
                working = false;
                ToggleOverlay(false);
                DisableProgressBar();
                MessageBox.Show(message);

            });
        }

        private void Timer_Callback(object o)
        {
            if (!working)
            {
                timer.Dispose();
                timer = null;
            }
            remainingSeconds--;
            if (remainingSeconds <= 0)
            {
                working = false;
                timer.Dispose();
                timer = null;
                Dispatcher.BeginInvoke(() =>
                {
                    MessageBox.Show(Strings.ConnectionError);
                    CancelUpdate_Button_Click(null, null);
                });
            }
            else
                Dispatcher.BeginInvoke(() =>
                {
                    RemainingTime_Label.Text = Strings.RemainingTime + remainingSeconds + " s.";
                });
        }

        public void Save()
        {
            ToggleOverlay(true);
            Dictionary<string, object> data = new Dictionary<string, object>()
            {
                {"username", MainPage.currentAccount.username},
                {"pwd", MainPage.currentAccount.password},
                {"salt", DateTime.Now.Millisecond},
                {"Title", Title_Area.Text},
                {"Text", Text_Area.Text}
            };
            if (SelectedNote.Id != 0)
                data.Add("Id", SelectedNote.Id);
            if (ImageModified)
                data.Add("image", byteArray);
            PostSubmitter post = new PostSubmitter() { url = "http://fboscari.altervista.org/Notes/save_note_phone.php", parameters = data };
            post.Submit((w) =>
            {
                Dispatcher.BeginInvoke(() =>
                {
                    ToggleOverlay(false);
                    int val = 0;
                    //MessageBox.Show(w);
                    //return;
                    if (!Int32.TryParse(w, out val))
                    {
                        MessageBox.Show(Strings.GeneralError);
                        return;
                    }
                    if (val <= 0)
                    {
                        if (val == -1 || val == 0)
                        {
                            MessageBox.Show(Strings.UnknownEmail);
                            return;
                        }
                        if (val == -2)
                        {
                            MessageBox.Show(Strings.MissingData);
                            return;
                        }
                    }
                    else
                    {
                        SelectedNote.Title = Title_Area.Text;
                        SelectedNote.Text = Text_Area.Text;
                        var date = DateTime.Now;
                        SelectedNote.Modified = "" + date.Year + "-" + date.Month + "-" + date.Day;
                        SelectedNote.Modified += " " + (date.Hour < 10 ? "0" : "") + date.Hour + ":" +
                            (date.Minute < 10 ? "0" : "") + date.Minute + ":" +
                            (date.Second < 10 ? "0" : "") + date.Second;

                        if (SelectedNote.Id == 0)
                        {
                            SelectedNote.Id = val;
                            SelectedNote.Created = SelectedNote.Modified;
                            NotesPage.result.notes.Insert(0, SelectedNote);
                        }
                        if (pinTile)
                            AddTile();
                        else
                            MessageBox.Show(Strings.Saved);
                        pinTile = false;
                        Storage.SaveResult(NotesPage.result);
                        ImageModified = false;
                    }
                });
            });
        }

        public void Save_old()
        {
            ToggleOverlay(true);
            string url = "http://fboscari.altervista.org/Notes/save_note_phone.php";
            //url += Utils.GetUpdateLiveTileArgs(result, currentAccount.contract, currentAccount.username, currentAccount.password, currentAccount.number, currentAccount.showDate);
            var payload = "username=" + MainPage.currentAccount.username + "&pwd=" + MainPage.currentAccount.password +
                "&salt=" + DateTime.Now.Millisecond +
                "&Title=" + Title_Area.Text
                + "&Text=" + Text_Area.Text;

            if (SelectedNote.Id != 0)
                payload += "&Id=" + SelectedNote.Id;

            Storage.getHTMLwithPost(url, payload, w =>
            {

                Dispatcher.BeginInvoke(() =>
                {
                    ToggleOverlay(false);
                    int val = 0;
                    if (!Int32.TryParse(w, out val))
                    {
                        MessageBox.Show(Strings.GeneralError);
                        return;
                    }
                    if (val <= 0)
                    {
                        if (val == -1 || val == 0)
                        {
                            MessageBox.Show(Strings.UnknownEmail);
                            return;
                        }
                        if (val == -2)
                        {
                            MessageBox.Show(Strings.MissingData);
                            return;
                        }
                    }
                    else
                    {
                        SelectedNote.Title = Title_Area.Text;
                        SelectedNote.Text = Text_Area.Text;
                        var date = DateTime.Now;
                        SelectedNote.Modified = "" + date.Year + "-" + date.Month + "-" + date.Day;
                        SelectedNote.Modified += " " + (date.Hour < 10 ? "0" : "") + date.Hour + ":" +
                            (date.Minute < 10 ? "0" : "") + date.Minute + ":" +
                            (date.Second < 10 ? "0" : "") + date.Second;

                        if (SelectedNote.Id == 0)
                        {
                            SelectedNote.Id = val;
                            SelectedNote.Created = SelectedNote.Modified;
                            NotesPage.result.notes.Insert(0, SelectedNote);
                        }
                        if (pinTile)
                            AddTile();
                        else
                            MessageBox.Show(Strings.Saved);
                        pinTile = false;
                        Storage.SaveResult(NotesPage.result);
                        ImageModified = false;
                    }
                });
            },
            () =>
            {
                OnError(Strings.ConnectionError);

            });
        }


        public void Delete()
        {
            ToggleOverlay(true);
            string url = "http://fboscari.altervista.org/Notes/delete_note_phone.php?";
            //url += Utils.GetUpdateLiveTileArgs(result, currentAccount.contract, currentAccount.username, currentAccount.password, currentAccount.number, currentAccount.showDate);
            url += "username=" + MainPage.currentAccount.username + "&pwd=" + MainPage.currentAccount.password +
                "&id=" + SelectedNote.Id +
                "&salt=" + DateTime.Now.Millisecond;
            Storage.getHTML(url, s =>
            {
                Dispatcher.BeginInvoke(() =>
                {
                    ToggleOverlay(false);
                    if (s == "")
                    {
                        NotesPage.result.notes.Remove(SelectedNote);

                        MessageBox.Show(Strings.Deleted);

                        NavigationService.GoBack();
                    }
                    else
                    {
                        if (s == "-3")
                        {
                            NotesPage.result.notes.Remove(SelectedNote);
                            MessageBox.Show(Strings.NoteAlreadyDeleted);
                            NavigationService.GoBack();
                        }
                        else if (s == "-4")
                        {
                            MessageBox.Show(Strings.MissingData);
                        }
                        else if (s == "-1")
                        {
                            MessageBox.Show(Strings.UnknownEmail);
                        }
                        else if (s == "-2")
                        {
                            MessageBox.Show(Strings.MissingData);
                        }
                        else
                        {
                            MessageBox.Show(Strings.GeneralError);
                            return;
                        }
                    }

                });
            },
            (e) =>
            {
                OnError(Strings.ConnectionError);

            });
        }


        private void Title_Area_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter)
            {
                Text_Area.Focus();
            }

        }

        private void EnableProgressBar()
        {
            Dispatcher.BeginInvoke(() =>
            {
                ToggleProgressBar.IsEnabled = true;
                ToggleProgressBar.IsIndeterminate = true;
                ToggleProgressBar.Visibility = System.Windows.Visibility.Visible;
            });
        }
        private void DisableProgressBar()
        {
            Dispatcher.BeginInvoke(() =>
            {
                ToggleProgressBar.IsEnabled = false;
                ToggleProgressBar.IsIndeterminate = false;
                ToggleProgressBar.Visibility = System.Windows.Visibility.Collapsed;
            });
        }

        private void CancelUpdate_Button_Click(object sender, RoutedEventArgs e)
        {
            ToggleOverlay(false);
        }

        private void PhoneApplicationPage_BackKeyPress(object sender, System.ComponentModel.CancelEventArgs e)
        {


            if (working)
            {
                CancelUpdate_Button_Click(null, null);
                e.Cancel = true;
            }
            else
            {
                if (SelectedNote.Title != Title_Area.Text || SelectedNote.Text != Text_Area.Text)
                    if (MessageBox.Show(Strings.DiscardChanges, Strings.Confirm, MessageBoxButton.OKCancel) == MessageBoxResult.Cancel)
                        e.Cancel = true;
            }
        }


        private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
        {
            if (!App.ViewModel.IsDataLoaded)
            {
                App.ViewModel.LoadData();
            }
        }

        private void Pin_Button_Click(object sender, EventArgs e)
        {
            if (Title_Area.Text == "")
            {
                MessageBox.Show(Strings.TitleCannotBeEmpty);
                return;
            }
            if (ShellTile.ActiveTiles.ToList().Count >= MaxTiles)
            {
                MessageBox.Show(Strings.MaxTiles);
                return;
            }
            if (SelectedNote.Id == 0)
            {
                if (MessageBox.Show(Strings.SaveRequested, Strings.Save, MessageBoxButton.OKCancel) == MessageBoxResult.Cancel)
                    return;
                pinTile = true;
                Save_Button_Click(null, null);
                return;
            }
            AddTile();
        }
        private bool pinTile = false;
        private const int MaxTiles = 5;
        private static void AddTile()
        {
            try
            {
                var uri = new Uri("/NotePage.xaml?id=" + SelectedNote.Id, UriKind.Relative);
                StandardTileData tile = new StandardTileData();
                tile.Title = SelectedNote.Title;
                //tile.BackContent = note.Text;
                tile.BackContent = SelectedNote.Modified;
                ShellTile.Create(uri, tile);
            }
            catch (Exception ex)
            {
                ex.ToString();
            }
        }

        private void CapturePhoto_Button_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                cameraCaptureTask.Show();
            }
            catch (System.InvalidOperationException ex)
            {
                ex.ToString();
                MessageBox.Show("An error occurred.");
            }
        }

        void cameraCaptureTask_Completed(object sender, PhotoResult e)
        {
            if (e.TaskResult == TaskResult.OK)
            {
                //MessageBox.Show(e.ChosenPhoto.Length.ToString());

                //Code to display the photo on the page in an image control named myImage.
                System.Windows.Media.Imaging.BitmapImage bmp = new System.Windows.Media.Imaging.BitmapImage();
                bmp.SetSource(e.ChosenPhoto);
                Image.Source = bmp;
                ImageModified = true;
                Image.Visibility = System.Windows.Visibility.Visible;
                SelectedNote.Type = 1;
                using (MemoryStream ms = new MemoryStream())
                {
                    WriteableBitmap btmMap = new WriteableBitmap(bmp);

                    // write an image into the stream
                    Extensions.SaveJpeg(btmMap, ms, bmp.PixelWidth, bmp.PixelHeight, 0, 100);

                    byteArray = ms.ToArray();
                }
            }
        }
    }


}